#include <algorithm>
#include <ctime>
#include <functional>
#include <iostream>
#include <map>

/*
std::function<> 可以绑定函数对象（仿函数 普通函数 lambda表达式）
*/
void foo1() {
    std::cout << "hello, cpp" << std::endl;
}

void foo2(const std::string& str) {
    std::cout << str << std::endl;
}

int sum(int a, int b) {
    return a + b;
}

class Foo {
public:
    void foo3(const std::string& str) {
        std::cout << str << std::endl;
    }
};

class Bar {
public:
    void operator()() {
        std::cout << "this is a function object." << std::endl;
    }
};

int main() {
    // 使用函数指针
    void (*pfunc1)();
    void (*pfunc2)(const std::string&);
    int (*pfunc3)(int, int);
    void (*pfunc4)(Foo*, const std::string&);

    pfunc1 = &foo1;
    pfunc2 = &foo2;
    pfunc3 = &sum;
    pfunc1();
    pfunc2("hello, world");
    std::cout << pfunc3(1, 1) << std::endl;

    // 使用std::funciton
    std::function<void()> ffunc1 = &foo1;
    std::function<void(const std::string& str)> ffunc2 = &foo2;
    std::function<int(int, int)> ffunc3 = &sum;
    // 使用std::function 绑定 类的成员方法
    std::function<void(Foo*, const std::string&)> ffunc4 = &Foo::foo3;

    ffunc1();
    ffunc2("hello, function");
    std::cout << ffunc3(1, 1) << std::endl;
    Foo f;
    ffunc4(&f, "hello, it's me.");

    // 使用std::function 绑定 函数对象
    Bar bar;
    bar();

    ffunc1 = bar;
    ffunc1();

    ffunc1 = []() { std::cout << "this is a lambda." << std::endl; };
    ffunc1();
}
